import datetime

from PySide6.QtCore import QSize, Qt, QTime
from PySide6.QtGui import QAction, QFont
from PySide6.QtWidgets import QMainWindow, QStyle, QMenuBar, QMenu, QWidget, QHBoxLayout, QTabWidget, QFrame, \
    QVBoxLayout, QGroupBox, QPushButton, QCalendarWidget, QScrollArea, QLabel, QFormLayout, QDateTimeEdit, QLineEdit, \
    QCheckBox, QSpinBox, QTimeEdit, QMessageBox

from AccountManager import AccountManager
from DBAccessor import DBAccessor
from NewWindow import NewWindow


class Main_Window(QMainWindow):
    Account_Manager: AccountManager = None
    RES_X: int = None
    RES_Y: int = None
    DBAccessor: DBAccessor = None
    FontPointSize: int = None
    NewWindow = None
    Schedules_After: list = None
    Schedules_Before: list = None
    Button_After: list = None
    Button_Before: list = None
    Button_All: list = None

    def __init__(self, account_manager: AccountManager, res_x: int, res_y: int, dbaccessor):
        super().__init__()
        self.Account_Manager = account_manager
        self.RES_X = res_x
        self.RES_Y = res_y
        self.DBAccessor = dbaccessor

        # 初始化参数
        # self.TitlePointSize = int(self.RES_Y / 75)
        # temp_font = QFont("微软雅黑", self.TitlePointSize)
        # temp_font.setBold(True)

        # 设置窗口属性
        self.setWindowIcon(self.style().standardPixmap(QStyle.StandardPixmap.SP_TrashIcon))  # 图标
        self.setWindowTitle("Magic Calendar: Main Window (*^▽^*)")
        self.resize(int(self.RES_X / 2), int(self.RES_Y / 2))  # 窗口大小
        self.setMinimumSize(QSize(int(self.RES_X / 2), int(self.RES_Y / 2)))  # 最小窗口大小

        # 设置MainWindow的菜单栏
        # self.menubar = QMenuBar(self)  # 构造一个QMenuBar
        # self.setMenuBar(self.menubar)  # 将QMenuBar设为MainWindow的菜单栏
        #
        # self.menu_account = QMenu(self.menubar)  # 构造一个QMenu，这是菜单栏上显示的按钮
        # self.menu_account.setTitle("账号")
        # self.menubar.addAction(self.menu_account.menuAction())  # 将QMenu添加到QMenuBar上
        #
        # self.action_login_info = QAction(self)  # 构造一个QAction，这是QMenu下的选项（其实QMenu下也可以是QMenu）
        # self.action_login_info.setText("账号信息")  # 设置QAction的文本
        # self.action_login_info.setIcon(
        #     self.style().standardIcon(QStyle.StandardPixmap.SP_DialogDiscardButton))  # 设置QAction的图标
        # self.menu_account.addAction(self.action_login_info)  # 将QAction添加到QMenu上
        # self.action_logout = QAction(self)
        # self.action_logout.setText("退出登录")
        # self.action_logout.setIcon(
        #     self.style().standardIcon(QStyle.StandardPixmap.SP_DialogDiscardButton))  # 设置QAction的图标
        # self.menu_account.addAction(self.action_logout)

        # 设置MainWindow的中心区域QWidget
        self.widget_central = QWidget(self)  # 构造一个QWidget
        self.setCentralWidget(self.widget_central)  # 将QWidget设为MainWindow的中心区域
        self.layout_h_main = QHBoxLayout(self.widget_central)  # 主界面布局，采用水平分布

        # 左侧日程选择区域
        self.tab_widget_schedule = QTabWidget()  # 构造左侧的QTabWidget，选择已完成、未完成、全部日程
        self.layout_h_main.addWidget(self.tab_widget_schedule)  # 将QTabWidget添加到主界面布局中
        self.tab_widget_schedule.setMaximumWidth(int(self.RES_X / 6))  # 设置QTabWidget的最大宽度

        # 设置未完成区域
        self.widget_unfinished = QWidget()  # 构造未完成区域的QWidget
        self.tab_widget_schedule.addTab(self.widget_unfinished, "未完成")  # 添加Tab
        self.layout_v_schedule_unfinished = QVBoxLayout(self.widget_unfinished)  # 全部区域布局
        # 设置带滚动条的日程按钮列表
        self.scroll_area_unfinished = QScrollArea()  # 构造滚动区域
        self.layout_v_schedule_unfinished.addWidget(self.scroll_area_unfinished)  # 添加滚动区域到“未完成”Tab中
        self.scroll_area_unfinished.setWidgetResizable(True)  # 设置滚动条可被重新设置大小
        self.scroll_area_widget_unfinished = QWidget()  # 构造滚动区域内的Widget
        self.scroll_area_unfinished.setWidget(self.scroll_area_widget_unfinished)  # 设置滚动区域内的Widget
        self.layout_v_scroll_area_unfinished = QVBoxLayout(self.scroll_area_widget_unfinished)  # 构造滚动区域布局内的Widget的布局
        self.layout_v_scroll_area_unfinished.setAlignment(Qt.AlignTop)  # 设置布局为顶部对齐

        # 设置已完成区域
        self.widget_finished = QWidget()
        self.tab_widget_schedule.addTab(self.widget_finished, "已完成")
        self.layout_v_schedule_finished = QVBoxLayout(self.widget_finished)  # 全部区域布局
        # 设置带滚动条的日程按钮列表
        self.scroll_area_finished = QScrollArea()  # 构造滚动区域
        self.layout_v_schedule_finished.addWidget(self.scroll_area_finished)  # 添加滚动区域到“已完成”Tab中
        self.scroll_area_finished.setWidgetResizable(True)  # 设置滚动条可被重新设置大小
        self.scroll_area_widget_finished = QWidget()  # 构造滚动区域内的Widget
        self.scroll_area_finished.setWidget(self.scroll_area_widget_finished)  # 设置滚动区域内的Widget
        self.layout_v_scroll_area_finished = QVBoxLayout(self.scroll_area_widget_finished)  # 构造滚动区域布局内的Widget的布局
        self.layout_v_scroll_area_finished.setAlignment(Qt.AlignTop)  # 设置布局为顶部对齐

        # 设置全部区域
        self.widget_all = QWidget()
        self.tab_widget_schedule.addTab(self.widget_all, "全部")
        self.layout_v_schedule_all = QVBoxLayout(self.widget_all)  # 全部区域布局
        # 设置带滚动条的日程按钮列表
        self.scroll_area_all = QScrollArea()  # 构造滚动区域
        self.layout_v_schedule_all.addWidget(self.scroll_area_all)  # 添加滚动区域到“全部”Tab中
        self.scroll_area_all.setWidgetResizable(True)  # 设置滚动条可被重新设置大小
        self.scroll_area_widget_all = QWidget()  # 构造滚动区域内的Widget
        self.scroll_area_all.setWidget(self.scroll_area_widget_all)  # 设置滚动区域内的Widget
        self.layout_v_scroll_area_all = QVBoxLayout(self.scroll_area_widget_all)  # 构造滚动区域布局内的Widget的布局
        self.layout_v_scroll_area_all.setAlignment(Qt.AlignTop)  # 设置布局为顶部对齐

        # 设置日历
        self.calendar = QCalendarWidget()
        self.layout_v_schedule_all.addWidget(self.calendar)
        self.calendar.setMaximumSize(int(self.RES_X / 6), int(self.RES_Y / 6))  # 设置QTabWidget的最大宽度

        # 更新按钮
        self.refresh_buttons()

        # 中间分隔线
        self.line_v = QFrame()
        self.layout_h_main.addWidget(self.line_v)
        self.line_v.setFrameShadow(QFrame.Raised)
        self.line_v.setFrameShape(QFrame.VLine)
        self.line_v.setLineWidth(0)
        self.line_v.setMidLineWidth(3)

        # 右侧日程详细信息显示与修改区域
        # 日程详细信息显示区域
        self.layout_v_info = QVBoxLayout()  # 右侧布局，采用垂直分布
        self.layout_h_main.addLayout(self.layout_v_info)
        self.group_box_info = QGroupBox()  # GroupBox 里面显示详细信息
        self.group_box_info.setTitle(
            "账号：" + str(self.Account_Manager.uid) + "  昵称：" + self.Account_Manager.nickname)
        self.group_box_info.setAlignment(Qt.AlignmentFlag.AlignRight)
        self.layout_v_info.addWidget(self.group_box_info)

        # GroupBox 内的布局
        self.layout_f_groupbox = QFormLayout(self.group_box_info)

        self.label_info_sid_title = QLabel("日程号：")  # 日程号
        self.label_info_sid_content = QLabel()
        self.layout_f_groupbox.addRow(self.label_info_sid_title, self.label_info_sid_content)

        self.label_info_sname_title = QLabel("日程标题：")  # 日程标题
        self.lineedit_info_sname_content = QLineEdit()
        self.layout_f_groupbox.addRow(self.label_info_sname_title, self.lineedit_info_sname_content)

        self.label_info_starttime_title = QLabel("开始时间：")  # 开始时间
        self.dtedit_info_starttime_content = QDateTimeEdit()
        self.dtedit_info_starttime_content.setDateTime(datetime.datetime.now())
        self.layout_f_groupbox.addRow(self.label_info_starttime_title, self.dtedit_info_starttime_content)

        self.label_info_endtime_title = QLabel("结束时间：")  # 结束时间
        self.dtedit_info_endtime_content = QDateTimeEdit()
        self.dtedit_info_endtime_content.setDateTime(datetime.datetime.now())
        self.layout_f_groupbox.addRow(self.label_info_endtime_title, self.dtedit_info_endtime_content)

        self.label_info_setting_title = QLabel("其他设置：")  # 其他设置
        self.layout_h_setting = QHBoxLayout()
        self.checkbox_info_abs = QCheckBox("忽略结束时间")
        self.checkbox_info_abs.clicked.connect(self.check_abs)
        self.layout_h_setting.addWidget(self.checkbox_info_abs)
        self.checkbox_info_cycle = QCheckBox("启用循环")
        self.checkbox_info_cycle.setChecked(True)
        self.checkbox_info_cycle.clicked.connect(self.check_cycle)
        self.layout_h_setting.addWidget(self.checkbox_info_cycle)
        self.layout_f_groupbox.addRow(self.label_info_setting_title, self.layout_h_setting)

        self.label_info_cycle_title = QLabel("循环时间")  # 循环时间
        self.layout_h_cycle = QHBoxLayout()
        self.spin_info_cycle_day_content = QSpinBox()
        self.layout_h_cycle.addWidget(self.spin_info_cycle_day_content)
        self.label_info_cycle_day_title = QLabel("天")
        self.layout_h_cycle.addWidget(self.label_info_cycle_day_title)
        self.spin_info_cycle_time_content = QTimeEdit()
        self.layout_h_cycle.addWidget(self.spin_info_cycle_time_content)
        self.label_info_cycle_time_title = QLabel("时分")
        self.layout_h_cycle.addWidget(self.label_info_cycle_time_title)
        self.layout_f_groupbox.addRow(self.label_info_cycle_title, self.layout_h_cycle)

        self.label_info_description_title = QLabel("日程描述：")  # 日程描述
        self.lineedit_info_description_content = QLineEdit()
        self.layout_f_groupbox.addRow(self.label_info_description_title, self.lineedit_info_description_content)

        self.label_info_uid_title = QLabel("发布者：")  # 发布者
        self.label_info_uid_content = QLabel()
        self.layout_f_groupbox.addRow(self.label_info_uid_title, self.label_info_uid_content)

        # 按钮区域
        self.layout_h_button = QHBoxLayout()  # 按钮布局，采用水平分布
        self.layout_v_info.addLayout(self.layout_h_button)
        self.button_confirm = QPushButton()  # 确认修改按钮
        self.layout_h_button.addWidget(self.button_confirm)
        self.button_confirm.setText("保存修改")
        self.button_confirm.clicked.connect(self.handle_confirm)
        self.button_new = QPushButton()  # 删除按钮
        self.layout_h_button.addWidget(self.button_new)
        self.button_new.setText("删除日程")
        self.button_new.clicked.connect(self.handle_delete)
        self.button_new = QPushButton()  # 新增按钮
        self.layout_h_button.addWidget(self.button_new)
        self.button_new.setText("新增日程")
        self.button_new.clicked.connect(self.handle_new)

    def handle_new(self):
        self.NewWindow = NewWindow(self, self.Account_Manager, self.RES_X, self.RES_Y, self.DBAccessor)
        self.NewWindow.show()

    def handle_confirm(self):
        if self.lineedit_info_sname_content.text() == '':
            QMessageBox.information(self, "出现了错误！", "标题不能为空！", QMessageBox.StandardButton.Ok)
            return
        if self.dtedit_info_starttime_content.dateTime() > self.dtedit_info_endtime_content.dateTime():
            QMessageBox.information(self, "出现了错误！", "开始时间不能大于结束时间！", QMessageBox.StandardButton.Ok)
            return
        if self.checkbox_info_cycle.isChecked():
            if self.spin_info_cycle_day_content.value() == 0 and self.spin_info_cycle_time_content.time() == QTime(0,
                                                                                                                   0):
                QMessageBox.information(self, "出现了错误！", "循环时间不能为0！", QMessageBox.StandardButton.Ok)
                return
        sid = int(self.label_info_sid_content.text())
        sname = self.lineedit_info_sname_content.text()
        starttime = datetime.datetime(self.dtedit_info_starttime_content.date().year(),
                                      self.dtedit_info_starttime_content.date().month(),
                                      self.dtedit_info_starttime_content.date().day(),
                                      self.dtedit_info_starttime_content.time().hour(),
                                      self.dtedit_info_starttime_content.time().minute(),
                                      self.dtedit_info_starttime_content.time().second())
        if self.checkbox_info_abs.isChecked():
            endtime = starttime
        else:
            endtime = datetime.datetime(self.dtedit_info_endtime_content.date().year(),
                                        self.dtedit_info_endtime_content.date().month(),
                                        self.dtedit_info_endtime_content.date().day(),
                                        self.dtedit_info_endtime_content.time().hour(),
                                        self.dtedit_info_endtime_content.time().minute(),
                                        self.dtedit_info_endtime_content.time().second())
        if self.checkbox_info_cycle.isChecked():
            cycle = str(self.spin_info_cycle_day_content.value()) + " " + str(
                self.spin_info_cycle_time_content.time().hour()) + " " + str(
                self.spin_info_cycle_time_content.time().minute())
        else:
            cycle = None
        description = self.lineedit_info_description_content.text()
        self.DBAccessor.update_schedule(sid, sname, starttime, endtime, cycle, description=description)
        self.refresh_buttons()

    def handle_delete(self):
        """
        删除日程
        """
        sid = int(self.label_info_sid_content.text())
        self.DBAccessor.delete_schedule(sid)
        self.refresh_buttons()

    def closeEvent(self, event) -> None:
        """
        重写关闭事件
        使主窗口退出时结束程序
        """
        if self.NewWindow is not None:
            self.NewWindow.close()
        super().closeEvent(event)

    def refresh_buttons(self):
        """
        添加日程按钮
        :param selector: 大于0则为已完成，等于0则取所有，小于0则为未完成
        """

        self.clear_all_buttons()  # 清空所有按钮

        self.Schedules_Before = self.DBAccessor.get_before_schedules(self.Account_Manager.uid)
        self.Schedules_After = self.DBAccessor.get_after_schedules(self.Account_Manager.uid)
        self.Button_After = []
        self.Button_Before = []
        self.Button_All = []

        # 设置“未完成”区域与“全部”区域的部分按钮
        for schedule in self.Schedules_After:
            button = QPushButton()
            button.setText(schedule[4] + "    [" +str(schedule[6]) + "]")  # 按钮的文本
            button.setObjectName(str(schedule[1]))  # 按钮的对象名是ID
            button.clicked.connect(self.choose_schedule)
            self.layout_v_scroll_area_unfinished.addWidget(button)
            self.Button_After.append(button)
            button2 = QPushButton()
            button2.setText(schedule[4] + "    [" +str(schedule[6]) + "]")
            button2.setObjectName(str(schedule[1]))
            button2.clicked.connect(self.choose_schedule)
            self.layout_v_scroll_area_all.addWidget(button2)
            self.Button_All.append(button2)

        # 分隔线
        line_h = QFrame()
        self.layout_v_scroll_area_all.addWidget(line_h)
        line_h.setFrameShadow(QFrame.Raised)
        line_h.setFrameShape(QFrame.HLine)
        line_h.setLineWidth(0)
        line_h.setMidLineWidth(3)

        # 设置“已完成”区域与“全部”区域的部分按钮
        for schedule in self.Schedules_Before:
            button = QPushButton()
            button.setText(schedule[4] + "    [" +str(schedule[6]) + "]")
            button.setObjectName(str(schedule[1]))
            button.clicked.connect(self.choose_schedule)
            self.layout_v_scroll_area_finished.addWidget(button)
            self.Button_Before.append(button)
            button2 = QPushButton()
            button2.setText(schedule[4] + "    [" +str(schedule[6]) + "]")
            button2.setObjectName(str(schedule[1]))
            button2.clicked.connect(self.choose_schedule)
            self.layout_v_scroll_area_all.addWidget(button2)
            self.Button_All.append(button2)

    def clear_all_buttons(self):
        while self.layout_v_scroll_area_finished.count() > 0:
            w = self.layout_v_scroll_area_finished.takeAt(0).widget()
            self.layout_v_scroll_area_finished.removeWidget(w)
            w.deleteLater()
        while self.layout_v_scroll_area_unfinished.count() > 0:
            w = self.layout_v_scroll_area_unfinished.takeAt(0).widget()
            self.layout_v_scroll_area_unfinished.removeWidget(w)
            w.deleteLater()
        while self.layout_v_scroll_area_all.count() > 0:
            w = self.layout_v_scroll_area_all.takeAt(0).widget()
            self.layout_v_scroll_area_all.removeWidget(w)
            w.deleteLater()

    def choose_schedule(self):
        sender = self.sender()
        sid = int(sender.objectName())
        schedule = self.DBAccessor.select_schedule(self.Account_Manager.uid, sid)
        self.label_info_sid_content.setText(str(schedule[1]))
        self.lineedit_info_sname_content.setText(str(schedule[4]))
        self.dtedit_info_starttime_content.setDateTime(schedule[5])
        self.dtedit_info_endtime_content.setDateTime(schedule[6])
        self.checkbox_info_abs.setChecked(schedule[5] == schedule[6])
        self.checkbox_info_cycle.setChecked(schedule[7] is not None)
        if schedule[7] is not None:
            splited = schedule[7].split(' ')
            self.spin_info_cycle_day_content.setValue(int(splited[0]))
            self.spin_info_cycle_time_content.setTime(QTime(int(splited[1]), int(splited[2])))
        self.lineedit_info_description_content.setText(schedule[3])
        publisher = self.DBAccessor.select_user(uid=schedule[2])[1]
        self.label_info_uid_content.setText(publisher)
        self.refresh_buttons()

    def check_abs(self):
        if self.checkbox_info_abs.isChecked():
            self.dtedit_info_endtime_content.setReadOnly(True)
            self.dtedit_info_endtime_content.setDateTime(self.dtedit_info_starttime_content.dateTime())
        else:
            self.dtedit_info_endtime_content.setReadOnly(False)

    def check_cycle(self):
        if self.checkbox_info_cycle.isChecked():
            self.spin_info_cycle_day_content.setReadOnly(False)
            self.spin_info_cycle_time_content.setReadOnly(False)
        else:
            self.spin_info_cycle_day_content.setReadOnly(True)
            self.spin_info_cycle_time_content.setReadOnly(True)
            self.spin_info_cycle_day_content.setValue(0)
            self.spin_info_cycle_time_content.setTime(QTime(0, 0))
